home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
PCW_C.ARJ
/
INT29C.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-17
|
7KB
|
172 lines
/***************************************************************/
/* File Id. INT29C.C. */
/* Author. Stan Milam. */
/* Date Written. 8 Oct. 91. */
/* */
/* (c) Copyright 1991, by Stan Milam. */
/* */
/* This code is responsible for writing DOS's standard output */
/* in a PCW window. It seems DOS sends all characters to be */
/* output to the screen through interrupt 29H. Here we capture*/
/* interrupt 29h and and print the characters in the PCW window*/
/* */
/***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include "pcw.i"
#include "pcwproto.h"
/* Function Declarations */
#ifdef __ZTC__
#define interrupt
void far *getvect( int nbr ) {
union REGS regs;
struct SREGS sregs;
regs.h.ah = (char) 0x35;
regs.h.al = (char) nbr;
int86x(0x21,®s,®s,&sregs);
return ( MK_FP(sregs.es, regs.x.bx) );
}
void setvect( int nbr, void far *isr ) {
union REGS regs;
struct SREGS sregs;
regs.h.ah = 0x25;
regs.h.al = (char) nbr;
regs.x.dx = FP_OFF(isr);
sregs.ds = FP_SEG(isr);
int86x(0x21,®s,®s,&sregs);
}
void (far *old_int29)(void);
#endif
#ifdef MSC
void (interrupt far *old_int29)(void);
#endif
#ifdef __TURBOC__
void interrupt (far *old_int29)(void);
#endif
#ifdef __POWERC
void interrupt (far *old_int29)(void);
#endif
extern void far interrupt Int29(void);
int far Int29c(int ax);
void far _Save_ES_DS_(void);
void far Save_Int29_Regs(void);
/**********************************************************/
/* set_int29() */
/* */
/* Set INT 29 to point to our assembler routine, but first*/
/* save the address of the old interrupt handler to call */
/* it if we need to. */
/**********************************************************/
int set_int29(void) {
#ifdef MSC
old_int29 = _dos_getvect(0x29); /* Get old int29 address */
_dos_setvect(0x29,Int29); /* Set Int 29 to point to */
#else /* Our code */
old_int29 = getvect(0x29);
setvect(0x29, Int29);
#endif
#ifdef __POWERC
Save_Int29_Regs(); /* Save Data & Extra Seg */
#endif
return(1);
}
/***************************************************************/
/* reset_int29() */
/* */
/* This function MUST BE CALLED IF YOU HAVE CAPTURED DOS OUTPUT*/
/* If this function is not called and your program ends then */
/* surely bad things will happen. */
/* */
/***************************************************************/
void reset_int29(void) {
#ifdef MSC
_dos_setvect(0x29,old_int29);
#else
setvect(0x29, old_int29);
#endif
}
/***************************************************************/
/* Int29c() */
/* */
/* This code is called by the assembly language interrupt hand-*/
/* ler and is responsible for handling the writing of a char- */
/* acter in the PCW window. It makes sure we are not writing */
/* outside of the window and scrolls the window when needed. */
/* If there is no active window or the active window is hidden */
/* then we simply return with a return code of -1. This sig- */
/* nals the assembly langauge handler to call the original DOS */
/* output interrupt. */
/* */
/* Inputs: The contents of AX register (char to print). */
/* Outputs: 1 if task accomplished, otherwise -1. */
/* */
/***************************************************************/
int far Int29c( int __ax ) {
WNDPTR *wnd;
union REGS regs;
int c_row, c_col, lrow, ucol, lcol;
if ((wnd = get_active_wnd()) == NULL)
return -1; /* Call original int29 */
if (wnd -> hideflag)
return 1; /* Can't show, window hidden */
ucol = wnd -> ucol; /* Dereference the boundries */
lrow = wnd -> lrow;
lcol = wnd -> lcol;
get_cursor_pos(&c_row, &c_col); /* Get cursor position */
switch ( __ax ) {
case '\n' :
if (c_row == (lrow - 1)) { /* Check for last row */
wscroll(wnd, 1, -1); /* Scroll wnd up 1 line */
return 1;
}
break;
case '\r' :
set_cursor_pos(c_row,ucol+1); /* Handle carriage return */
return ( 1 );
}
memset(®s, 0, sizeof(union REGS)); /* Clear psuedo regs */
regs.h.ah = 0xe; /* Set the registers */
regs.h.al = (char) __ax; /* Character in AX */
regs.h.bh = (char) wnd -> page; /* Active video page */
regs.h.bl = (char) wnd -> attr; /* Color in Bl */
regs.x.cx = 1;
int86(0x10, ®s, ®s); /* Call BIOS, write char and */
/* advance the cursor */
get_cursor_pos(&c_row, &c_col);
if (c_col == lcol) { /* Is last column? */
if (c_row == lrow-1) { /* If it is then is it last row */
wscroll(wnd, 1, -1); /* If it is scroll the window */
set_cursor_pos(lrow - 1, ucol + 1);/* And pos cursor to 1st column */
}
else set_cursor_pos(c_row+1, ucol+1); /* Not last row so positon */
} /* Next row,1st column of window */
return(1); /* Send back good return */
} /* And quit */